home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter21 / isohex21_2 / isohex21_2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-09  |  11.9 KB  |  484 lines

  1. /*****************************************************************************
  2. IsoHex21_2.cpp
  3. Ernest S. Pazera
  4. 09SEPT2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Requires the following libs:
  7. ddraw.lib, dxguid.lib
  8. Requires the following files:
  9. DDFuncs.h.cpp, GDICanvas.h/cpp, IsoMouseMap.h/cpp,
  10. IsoScroller.h/cpp, IsoTilePlotter.h/cpp, IsoTileWalker.h/cpp
  11. TileSet.h/cpp. IsoHexCore.h, IsoHexDefs.h
  12. IsoRenderer.h/cpp
  13. *****************************************************************************/
  14.  
  15. //////////////////////////////////////////////////////////////////////////////
  16. //INCLUDES
  17. //////////////////////////////////////////////////////////////////////////////
  18. #define WIN32_LEAN_AND_MEAN  
  19.  
  20. #include <windows.h>  
  21. #include "DDFuncs.h"
  22. #include "TileSet.h"
  23. #include "IsoHexCore.h"
  24. #include "IsoRenderer.h"
  25.  
  26. //////////////////////////////////////////////////////////////////////////////
  27. //DEFINES
  28. //////////////////////////////////////////////////////////////////////////////
  29. //name for our window class
  30. #define WINDOWCLASS "ISOHEX21"
  31. //title of the application
  32. #define WINDOWTITLE "IsoHex 21-2"
  33.  
  34. const int MAPWIDTH=40;
  35. const int MAPHEIGHT=40;
  36.  
  37. const int SCREENWIDTH=640;
  38. const int SCREENHEIGHT=480;
  39.  
  40. //road flags
  41. const int ROAD_NORTHEAST=1;
  42. const int ROAD_SOUTHEAST=2;
  43. const int ROAD_SOUTHWEST=4;
  44. const int ROAD_NORTHWEST=8;
  45.  
  46. //////////////////////////////////////////////////////////////////////////////
  47. //TYPEDEFS/STRUCTS
  48. //////////////////////////////////////////////////////////////////////////////
  49.  
  50. //////////////////////////////////////////////////////////////////////////////
  51. //PROTOTYPES
  52. //////////////////////////////////////////////////////////////////////////////
  53. bool Prog_Init();//game data initalizer
  54. void Prog_Loop();//main game loop
  55. void Prog_Done();//game clean up
  56.  
  57. //////////////////////////////////////////////////////////////////////////////
  58. //GLOBALS
  59. //////////////////////////////////////////////////////////////////////////////
  60. HINSTANCE hInstMain=NULL;//main application handle
  61. HWND hWndMain=NULL;//handle to our main window
  62.  
  63. //directdraw
  64. LPDIRECTDRAW7 lpdd=NULL;
  65. LPDIRECTDRAWSURFACE7 lpddsMain=NULL;
  66. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  67. LPDIRECTDRAWSURFACE7 lpddsFrame=NULL;
  68.  
  69. //tilesets
  70. CTileSet tsBack;
  71. CTileSet tsRoad;
  72.  
  73. //isohexcore components
  74. CTilePlotter TilePlotter;//plotter
  75. CTileWalker TileWalker;//walker
  76. CScroller Scroller;//scroller
  77. CMouseMap MouseMap;//mousemap
  78. CRenderer Renderer;//renderer
  79.  
  80. POINT ptScroll;//keep track of how quickly we scroll
  81.  
  82. //map location structure
  83. struct MapLocation
  84. {
  85.     bool bRoad;
  86.     int iRoad;
  87. };
  88.  
  89. MapLocation mlMap[MAPWIDTH][MAPHEIGHT];//map array
  90.  
  91. //rendering functionprototype
  92. void RenderFunc(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* rcClip,int xDst,int yDst,int xMap,int yMap);
  93. void CalcRoad();//calculate entire map
  94. void CalcRoad(int x,int y);//calculate for individual map location
  95. void CalcRoadNeighborhood(int x,int y);//calculate for a tile neighborhood
  96.  
  97. //////////////////////////////////////////////////////////////////////////////
  98. //WINDOWPROC
  99. //////////////////////////////////////////////////////////////////////////////
  100. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  101. {
  102.     //which message did we get?
  103.     switch(uMsg)
  104.     {
  105.     case WM_KEYDOWN:
  106.         {
  107.             switch(wParam)
  108.             {
  109.             case VK_ESCAPE:
  110.                 {
  111.                     DestroyWindow(hWndMain);
  112.                     return(0);
  113.                 }break;
  114.             }
  115.         }break;
  116.     case WM_DESTROY://the window is being destroyed
  117.         {
  118.  
  119.             //tell the application we are quitting
  120.             PostQuitMessage(0);
  121.  
  122.             //handled message, so return 0
  123.             return(0);
  124.  
  125.         }break;
  126.     case WM_PAINT://the window needs repainting
  127.         {
  128.             //a variable needed for painting information
  129.             PAINTSTRUCT ps;
  130.             
  131.             //start painting
  132.             HDC hdc=BeginPaint(hwnd,&ps);
  133.  
  134.             /////////////////////////////
  135.             //painting code would go here
  136.             /////////////////////////////
  137.  
  138.             //end painting
  139.             EndPaint(hwnd,&ps);
  140.                         
  141.             //handled message, so return 0
  142.             return(0);
  143.         }break;
  144.     }
  145.  
  146.     //pass along any other message to default message handler
  147.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  148. }
  149.  
  150.  
  151. //////////////////////////////////////////////////////////////////////////////
  152. //WINMAIN
  153. //////////////////////////////////////////////////////////////////////////////
  154. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  155. {
  156.     //assign instance to global variable
  157.     hInstMain=hInstance;
  158.  
  159.     //create window class
  160.     WNDCLASSEX wcx;
  161.  
  162.     //set the size of the structure
  163.     wcx.cbSize=sizeof(WNDCLASSEX);
  164.  
  165.     //class style
  166.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  167.  
  168.     //window procedure
  169.     wcx.lpfnWndProc=TheWindowProc;
  170.  
  171.     //class extra
  172.     wcx.cbClsExtra=0;
  173.  
  174.     //window extra
  175.     wcx.cbWndExtra=0;
  176.  
  177.     //application handle
  178.     wcx.hInstance=hInstMain;
  179.  
  180.     //icon
  181.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  182.  
  183.     //cursor
  184.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  185.  
  186.     //background color
  187.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  188.  
  189.     //menu
  190.     wcx.lpszMenuName=NULL;
  191.  
  192.     //class name
  193.     wcx.lpszClassName=WINDOWCLASS;
  194.  
  195.     //small icon
  196.     wcx.hIconSm=NULL;
  197.  
  198.     //register the window class, return 0 if not successful
  199.     if(!RegisterClassEx(&wcx)) return(0);
  200.  
  201.     //create main window
  202.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  203.  
  204.     //error check
  205.     if(!hWndMain) return(0);
  206.  
  207.     //if program initialization failed, then return with 0
  208.     if(!Prog_Init()) return(0);
  209.  
  210.     //message structure
  211.     MSG msg;
  212.  
  213.     //message pump
  214.     for(;;)    
  215.     {
  216.         //look for a message
  217.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  218.         {
  219.             //there is a message
  220.  
  221.             //check that we arent quitting
  222.             if(msg.message==WM_QUIT) break;
  223.             
  224.             //translate message
  225.             TranslateMessage(&msg);
  226.  
  227.             //dispatch message
  228.             DispatchMessage(&msg);
  229.         }
  230.  
  231.         //run main game loop
  232.         Prog_Loop();
  233.     }
  234.     
  235.     //clean up program data
  236.     Prog_Done();
  237.  
  238.     //return the wparam from the WM_QUIT message
  239.     return(msg.wParam);
  240. }
  241.  
  242. //////////////////////////////////////////////////////////////////////////////
  243. //INITIALIZATION
  244. //////////////////////////////////////////////////////////////////////////////
  245. bool Prog_Init()
  246. {
  247.     //create IDirectDraw object
  248.     lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
  249.  
  250.     //set display mode
  251.     lpdd->SetDisplayMode(SCREENWIDTH,SCREENHEIGHT,16,0,0);
  252.  
  253.     //create primary surface
  254.     lpddsMain=LPDDS_CreatePrimary(lpdd,1);
  255.  
  256.     //get back buffer
  257.     lpddsBack=LPDDS_GetSecondary(lpddsMain);
  258.  
  259.     //create the frame buffer
  260.     lpddsFrame=LPDDS_CreateOffscreen(lpdd,640,480);
  261.  
  262.     //load in the mousemap
  263.     MouseMap.Load("MouseMap.bmp");
  264.  
  265.     //set up the tile plotter
  266.     TilePlotter.SetMapType(ISOMAP_DIAMOND);//diamond mode
  267.     TilePlotter.SetTileSize(MouseMap.GetWidth(),MouseMap.GetHeight());//grab width and height from mousemap
  268.  
  269.     //set up tile walker to diamond mode
  270.     TileWalker.SetMapType(ISOMAP_DIAMOND);
  271.  
  272.     //set up screeen space
  273.     RECT rcTemp;
  274.     SetRect(&rcTemp,0,0,640,480);
  275.     Scroller.SetScreenSpace(&rcTemp);
  276.  
  277.     //load in tiles and cursor
  278.     tsBack.Load(lpdd,"backgroundts.bmp");
  279.     tsRoad.Load(lpdd,"roadts.bmp");
  280.  
  281.     //grab tile extent from tileset
  282.     CopyRect(&rcTemp,&tsBack.GetTileList()[0].rcDstExt);
  283.  
  284.     //calculate the worldspace
  285.     Scroller.CalcWorldSpace(&TilePlotter,&rcTemp,MAPWIDTH,MAPHEIGHT);
  286.  
  287.     //calculate the mousemap reference point
  288.     MouseMap.CalcReferencePoint(&TilePlotter,&rcTemp);
  289.  
  290.     //calculate anchor space
  291.     Scroller.CalcAnchorSpace();
  292.  
  293.     //set wrap modes for scroller
  294.     Scroller.SetHWrapMode(WRAPMODE_CLIP);
  295.     Scroller.SetVWrapMode(WRAPMODE_CLIP);
  296.  
  297.     //set scroller anchor to (0,0)
  298.     Scroller.GetAnchor()->x=0;
  299.     Scroller.GetAnchor()->y=0;
  300.  
  301.     //attach scrolelr and tilewalker to mousemap
  302.     MouseMap.SetScroller(&Scroller);
  303.     MouseMap.SetTileWalker(&TileWalker);
  304.  
  305.     //set up the map to a random tilefield
  306.     int x;
  307.     int y;
  308.     for(x=0;x<MAPWIDTH;x++)
  309.     {
  310.         for(y=0;y<MAPHEIGHT;y++)
  311.         {
  312.             if(rand()&1)
  313.             {
  314.                 mlMap[x][y].bRoad=true;
  315.             }
  316.             else
  317.             {
  318.                 mlMap[x][y].bRoad=false;
  319.             }
  320.         }
  321.     }
  322.  
  323.     //calculate the fringe
  324.     CalcRoad();
  325.  
  326.     //calculate the extent rect
  327.     RECT rcExtent;
  328.     CopyRect(&rcExtent,&tsBack.GetTileList()[0].rcDstExt);//set to background extent
  329.  
  330.     //set up the renderer
  331.     Renderer.SetBackBuffer(lpddsBack);
  332.     Renderer.SetExtentRect(&rcExtent);
  333.     Renderer.SetFrameBuffer(lpddsFrame);
  334.     Renderer.SetMapSize(MAPWIDTH,MAPHEIGHT);
  335.     Renderer.SetMouseMap(&MouseMap);
  336.     Renderer.SetPlotter(&TilePlotter);
  337.     Renderer.SetRenderFunction(RenderFunc);
  338.     Renderer.SetScroller(&Scroller);
  339.     Renderer.SetUpdateRectCount(100);
  340.     Renderer.SetWalker(&TileWalker);
  341.  
  342.     //update the entire screenspace
  343.     Renderer.AddRect(Scroller.GetScreenSpace());
  344.  
  345.     return(true);//return success
  346. }
  347.  
  348. //////////////////////////////////////////////////////////////////////////////
  349. //CLEANUP
  350. //////////////////////////////////////////////////////////////////////////////
  351. void Prog_Done()
  352. {
  353.     //release frame buffer
  354.     LPDDS_Release(&lpddsFrame);
  355.  
  356.     //release main/back surfaces
  357.     LPDDS_Release(&lpddsMain);
  358.  
  359.     //release directdraw
  360.     LPDD_Release(&lpdd);
  361. }
  362.  
  363. //////////////////////////////////////////////////////////////////////////////
  364. //MAIN GAME LOOP
  365. //////////////////////////////////////////////////////////////////////////////
  366. void Prog_Loop()
  367. {
  368.     //grab mouse position
  369.     POINT ptMouse;
  370.     GetCursorPos(&ptMouse);
  371.  
  372.     //calc scrolling
  373.     //horizontal
  374.     ptScroll.x=0;
  375.     if(ptMouse.x<8) ptScroll.x=ptMouse.x-8;
  376.     if(ptMouse.x>SCREENWIDTH-8) ptScroll.x=ptMouse.x-(SCREENWIDTH-8);
  377.     //vertical
  378.     ptScroll.y=0;
  379.     if(ptMouse.y<8) ptScroll.y=ptMouse.y-8;
  380.     if(ptMouse.y>SCREENHEIGHT-8) ptScroll.y=ptMouse.y-(SCREENHEIGHT-8);
  381.  
  382.     //scroll the frame by ptScroll
  383.     Renderer.ScrollFrame(ptScroll.x,ptScroll.y);
  384.     //update the frame
  385.     Renderer.UpdateFrame();
  386.     //flip to show the back buffer
  387.     lpddsMain->Flip(0,DDFLIP_WAIT);
  388. }
  389.  
  390. void RenderFunc(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* rcClip,int xDst,int yDst,int xMap,int yMap)
  391. {
  392.     //put down a land tile
  393.     tsBack.ClipTile(lpddsDst,rcClip,xDst,yDst,0);
  394.     //check for a road
  395.     if(mlMap[xMap][yMap].bRoad)
  396.     {
  397.         //put the road image
  398.         tsRoad.ClipTile(lpddsDst,rcClip,xDst,yDst,mlMap[xMap][yMap].iRoad);
  399.     }
  400. }
  401.  
  402. void CalcRoad()
  403. {
  404.     //loop through x
  405.     for(int x=0;x<MAPWIDTH;x++)
  406.     {
  407.         //loop through y
  408.         for(int y=0;y<MAPHEIGHT;y++)
  409.         {
  410.             //calc the fringe
  411.             CalcRoad(x,y);
  412.         }
  413.     }
  414. }
  415.  
  416. void CalcRoad(int x,int y)//calculate for individual map location
  417. {
  418.     //range checking
  419.     if(x<0) return;
  420.     if(y<0) return;
  421.     if(x>=MAPWIDTH) return;
  422.     if(y>=MAPHEIGHT) return;
  423.     //calculate the tile neighborhood
  424.     bool Neighbor[8];
  425.     //store starting point
  426.     POINT ptStart;
  427.     ptStart.x=x;
  428.     ptStart.y=y;
  429.     //next map location
  430.     POINT ptNext;
  431.     for(int dir=0;dir<8;dir++)
  432.     {
  433.         //walk to neighbor
  434.         ptNext=TileWalker.TileWalk(ptStart,(ISODIRECTION)dir);
  435.         //range check 
  436.         if(ptNext.x<0 || ptNext.y<0 || ptNext.x>=MAPWIDTH || ptNext.y>=MAPHEIGHT)
  437.         {
  438.             //out of bounds
  439.             Neighbor[dir]=0;
  440.         }
  441.         else
  442.         {
  443.             //check map location
  444.             if(mlMap[ptNext.x][ptNext.y].bRoad)
  445.             {
  446.                 //road
  447.                 Neighbor[dir]=1;
  448.             }
  449.             else
  450.             {
  451.                 //no road
  452.                 Neighbor[dir]=0;
  453.             }
  454.         }
  455.     }
  456.     //clear road flags
  457.     mlMap[x][y].iRoad=0;
  458.     //add road flags as appropriate
  459.     if(Neighbor[ISO_NORTHEAST]) mlMap[x][y].iRoad|=ROAD_NORTHEAST;
  460.     if(Neighbor[ISO_SOUTHEAST]) mlMap[x][y].iRoad|=ROAD_SOUTHEAST;
  461.     if(Neighbor[ISO_SOUTHWEST]) mlMap[x][y].iRoad|=ROAD_SOUTHWEST;
  462.     if(Neighbor[ISO_NORTHWEST]) mlMap[x][y].iRoad|=ROAD_NORTHWEST;
  463. }
  464.  
  465. void CalcRoadNeighborhood(int x,int y)//calculate for a tile neighborhood
  466. {
  467.     //send tile(x,y) to calculate fringe function
  468.     CalcRoad(x,y);
  469.     //store center point
  470.     POINT ptCenter;
  471.     ptCenter.x=x;
  472.     ptCenter.y=y;
  473.     POINT ptNeighbor;
  474.     //loop through directions
  475.     for(int dir=0;dir<8;dir++)
  476.     {
  477.         //determine neighbor
  478.         ptNeighbor=TileWalker.TileWalk(ptCenter,(ISODIRECTION)dir);
  479.         //send neighbor to calculation function
  480.         CalcRoad(ptNeighbor.x,ptNeighbor.y);
  481.     }
  482. }
  483.  
  484.